package cn.coder.jdbc.mapper;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import cn.coder.jdbc.support.ResultMapper;
import cn.coder.jdbc.util.JdbcUtils;

public final class ProcedureMapper implements ResultMapper<Object[]> {

	private String name;
	private Object[] args;

	public ProcedureMapper(String name, Object[] objects) {
		this.name = name;
		this.args = objects;
	}

	@Override
	public Statement makeStatement(Connection conn) throws SQLException {
		CallableStatement stmt = conn.prepareCall(this.name);
		JdbcUtils.bindArgs(stmt, this.args);
		return stmt;
	}

	@Override
	public Object[] doStatement(Statement stmt) throws SQLException {
		((CallableStatement) stmt).execute();

		ParameterMetaData metaData = ((CallableStatement) stmt).getParameterMetaData();
		int length = metaData.getParameterCount();
		Object[] result = new Object[length];
		for (int i = 1; i <= length; i++) {
			if (metaData.getParameterMode(i) == ParameterMetaData.parameterModeInOut
					|| metaData.getParameterMode(i) == ParameterMetaData.parameterModeOut)
				result[i - 1] = ((CallableStatement) stmt).getObject(i);
			else
				result[i - 1] = this.args[i - 1];
		}
		return result;
	}

}
